Monthly Archives: February 2014

Project Update: Nov. 26, 2013

_IGP9138I’ve been doing run tests on the units over the last week or so taking samples every minute (simulating about 30 days in the field). Data logged well, but band-gap monitoring reported Vcc wobbling by more than half a volt once the supply fell below 3.8 volts. Not sure what to make the cutoff voltage though and I wonder if that monitoring code is a bit flaky?  Even so, the accelerometer ran smoothly with very little noise on the axis readings during the wobbling voltages. But I did see a bit of downward drift in the internal temperatures being reported by the RTC, and the accelerometer. Not sure what caused that.

The whole unit is showing about 60mv drop on the 3 AA no-name battery pack per 100 readings. That’s about a days worth of operation at 15 minutes sample intervals, which projects out to about 45 days of operation on a 6 pack before I hit 2.7 v (my current best guess at a ‘safe’ minimum voltage for SD card writes). Not great performance I admit, but good enough for some field testing anyway.

And a last minute batch of new boards arrived today from TinyCircuits, so I will have at least one full set of spare parts in the box if I need it…Sweet!

Q: I wonder what would happen if I let the little loggers run right down to the point where the internal brown out detector kicks in and shuts down the whole system? Would this hurt the SD card? No time for destructive tests now though, as I am on the plane to Mexico tomorrow morning.

Q: I wonder what other data I could be reading out of that bma250 accelerometer? If it’s got an internal bump detector, does that mean that it’s internally calculating theta on the fly? In which case I could read it out directly over I2C as well?

Q: I still have that old mma7361 lying around that I’d like to put in service, but I’m not sure how stable an analog device would be with an unregulated power supply?
A: I found a discussion of the issue over at avrfreaks. It looks like they the relative measurements stay the same, so if you are recording vcc, you can do the correction.


And talkin’ the talk…

Now that I think about it, that last bit of bloggy catharsis will probably be read to the end by maybe three people on the whole internet…if I include my mom. I’m sure the real coders felt a yawn coming on at the second line, and aside from the two other newbies out there at the “Just reading anything I can find.” stage, everyone else is probably thinking “Ok! Enough already… just gimme the code!”

So here you go. My first stable datalogger build* for a Tinyduino stack consisting of: a processor board, a BMA250 accelerometer sheild,  the microSD adapter, and a protoboard, jumpered to a chronodot RTC. The whole thing runs ‘unregulated’ off of 3 AA batteries, so I keep an eye on the bandgap voltage to (hopefully) stop data writes to the SD card when the battery voltage gets too low. But this part has not been tested yet, so don’t trust your life, or data for your thesis, to that kludge. Build yourself a real voltage divider!

*This scrapbook of code was cobbled together from the work of other people who actually know what they are doing, and my only real contribution was the hours I spent wading through forum threads collecting examples, before bolting this Frankenstein together.  So I take no credit for any of it, and provide no guarantees whatsoever that it wont brick your system the first time you run it. I also hope that anyone I’ve missed in the credits, forgives the accidental oversight, as some details get lost in the process of all that cutting and pasting.

// Date, Time and Alarm functions using a DS3231 chronodot RTC connected via I2C // and Wire library from https://github.com/MrAlvin/RTClib
// based largely on Jean-Claude Wippler from JeeLab’s https://github.com/jcw
// Clear alarm interupt code from http://forum.arduino.cc/index.php?topic=109062.0
// Get temp from http://forum.arduino.cc/index.php/topic,22301.0.html [which does not use the RTCLIB!]
// BMA250_I2C_Sketch.pde – from
// https://tiny-circuits.com/learn/using-the-accelerometer-tinyshield/
// which links to
// http://www.dsscircuits.com/accelerometer-bma250.html
// combined with internal voltage reading trick from:
// http://forum.arduino.cc/index.php/topic,15629.0.html
// floats to string conversion: http://dereenigne.org/arduino/arduino-float-to-string

//note: angle brackets which should be around library names are missing here due to formatting weirdness in WordPress

#include SD.h
#include Wire.h
#include SPI.h // not used here, but needed to prevent a RTClib compile error
#include avr/sleep.h
#include RTClib.h

#ifndef cbi //defs for stopping the ADC during sleep mode
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

#define DS3231_I2C_ADDRESS 104 //for the RTC temp reading function

#define BMA250 0x18
#define BW 0x08 //7.81Hz bandwith
#define GSEL 0x03 // set range 0x03 – 2g, 0x05 – 4, 0x08 – 8g, 0x0C – 16g
//#define DELAY 10000 is this line an orphan?

RTC_DS3231 RTC;
byte Alarmhour = 1;
byte Alarmminute = 1;
byte dummyRegister;
int INTERRUPT_PIN = 2;
volatile int state = LOW;
volatile boolean clockInterrupt = false;
int SampleInterval = 1;
// power-down time in minutes before interupt triggers next sample

byte tMSB, tLSB; //for the RTC temp reading function
float temp3231;

const int chipSelect = 10; //sd card chip select

uint8_t dataArray[16];
//variables for accellerometer reading
int8_t BMAtemp;
float BMAtempfloat;
int x,y,z;
String BMAdata; //for passing back data from bma read function
char TimeStampbuffer[ ]= “0000/00/00,00:00:00, “;

int ledpin = 13; //led indicator pin

void setup () {

pinMode(INTERRUPT_PIN, INPUT);
digitalWrite(INTERRUPT_PIN, HIGH);//pull up the interrupt pin
pinMode(13, OUTPUT); // initialize the LED pin as an output.
digitalWrite(13, HIGH); // turn the LED on to warn against SD card removal

Serial.begin(9600);
Wire.begin();
RTC.begin();
//RTC.adjust(DateTime(__DATE__, __TIME__));
//the above line set the time with code compile time – you only run this line ONCE!
clearClockTrigger(); //stops RTC from holding the interrupt low if system reset
// time for next alarm
DateTime now = RTC.now();
Alarmhour = now.hour();
Alarmminute = now.minute()+ SampleInterval ;
if (Alarmminute > 59) { //error catch – if Alarmminute=60 the interrupt never triggers due to rollover
Alarmminute = 0; Alarmhour = Alarmhour+1; if (Alarmhour > 23) {Alarmhour =0;}
}

initializeBMA(); //initialize the accelerometer

//get the SD card ready
pinMode(chipSelect, OUTPUT); //make sure that the default chip select pin is set to output, even if you don’t use it
Serial.print(“Initializing SD card…”);
if (!SD.begin(chipSelect)) { // see if the card is present and can be initialized:
Serial.println(“Card failed, or not present”); // don’t do anything more:
return;
}
Serial.println(“card initialized.”);
File dataFile = SD.open(“datalog.txt”, FILE_WRITE); //PRINT THE DATA FILE HEADER
if (dataFile) { // if the file is available, write to it:
dataFile.println(“YYYY/MM/DD, HH:MM:SS, Vcc(mV), X = , Y = , Z = , BMATemp (C) , RTC temp (C)”);
dataFile.close();
}
else { //if the file isn’t open, pop up an error:
Serial.println(“Error opening datalog.txt file!”);
}
}

void loop () {

if (clockInterrupt) {
clearClockTrigger();
}

//read in our data
BMAdata = String(“”); //clear out the datastring
read3AxisAcceleration(); //loads up the dataString
DateTime now = RTC.now(); // Read the time and date from the RTC
sprintf(TimeStampbuffer, “%04d/%02d/%02d,%02d:%02d:%02d,”, now.year(), now.month(), now.day(), now.hour(), now.minute(), now.second());
Serial.println(“Timestamp Y/M/D, HH:MM:SS, Vcc = , X = , Y = , Z = , BMATemp (C) , RTC temp (C)”);
Serial.print(TimeStampbuffer); Serial.print(readVcc()); Serial.print(“,”);
Serial.print(BMAdata); Serial.print(“,”); Serial.println(get3231Temp());

//write data to the SD card
// note that only one file can be open at a time,so you have to close this one before opening another.
File dataFile = SD.open(“datalog.txt”, FILE_WRITE);

if (dataFile) { // if the file is available, write to it:
dataFile.print(TimeStampbuffer);dataFile.print(readVcc()); dataFile.print(“,”);
dataFile.print(BMAdata); dataFile.print(“,”); dataFile.println(get3231Temp());
dataFile.close();
}
else { //if the file isn’t open, pop up an error:
Serial.println(“Error opening datalog.txt file”);
}

// setNextAlarmTime();
Alarmhour = now.hour(); Alarmminute = now.minute()+SampleInterval;
if (Alarmminute > 59) { //error catch – if alarmminute=60 the interrupt never triggers due to rollover!
Alarmminute =0; Alarmhour = Alarmhour+1; if (Alarmhour > 23) {Alarmhour =0;}
}
RTC.setAlarm1Simple(Alarmhour, Alarmminute);
RTC.turnOnAlarm(1);

Serial.print(“Alarm Enabled at: “);
Serial.print(now.hour(), DEC); Serial.print(‘:’); Serial.println(now.minute(), DEC);
Serial.print(“Going to Sleep for “); Serial.print(SampleInterval);Serial.println(” minutes.”);
delay(100);
//a delay long enough to boot out the serial coms before sleeping.

sleepNow();

//Serial.println(“Alarm 1 has been Triggered!”);
}

void sleepNow() {
digitalWrite(13, LOW);
cbi(ADCSRA,ADEN); // Switch ADC OFF
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
attachInterrupt(0,clockTrigger, LOW);
sleep_mode();
//HERE AFTER WAKING UP
sleep_disable();
detachInterrupt(0);
sbi(ADCSRA,ADEN); // Switch ADC converter ON
pinMode(13, OUTPUT); digitalWrite(13, HIGH);
// turn the LED on to warn against SD card removal
// But I have some conflict between the SD chip select line, and the led – so the darned thing never lit!
}

void clockTrigger() {
clockInterrupt = true; //do something quick, flip a flag, and handle in loop();
}

void clearClockTrigger()
{
Wire.beginTransmission(0x68); //Tell devices on the bus we are talking to the DS3231
Wire.write(0x0F); //Tell the device which address we want to read or write
Wire.endTransmission(); //Before you can write to and clear the alarm flag you have to read the flag first!
Wire.requestFrom(0x68,1); // Read one byte
dummyRegister=Wire.read(); // In this example we are not interest in actually using the bye
Wire.beginTransmission(0x68); //Tell devices on the bus we are talking to the DS3231
Wire.write(0x0F); //Tell the device which address we want to read or write
Wire.write(0b00000000); //Write the byte. The last 0 bit resets Alarm 1
Wire.endTransmission();
clockInterrupt=false; //Finally clear the flag we used to indicate the trigger occurred
}

// could also use RTC.getTemperature() from the library here as in:
//RTC.convertTemperature(); //convert current temperature into registers
//Serial.print(RTC.getTemperature()); //read registers and display the temperature

float get3231Temp()
{
//temp registers (11h-12h) get updated automatically every 64s
Wire.beginTransmission(DS3231_I2C_ADDRESS);
Wire.write(0x11);
Wire.endTransmission();
Wire.requestFrom(DS3231_I2C_ADDRESS, 2);

if(Wire.available()) {
tMSB = Wire.read(); //2’s complement int portion
tLSB = Wire.read(); //fraction portion

temp3231 = ((((short)tMSB << 8 | (short)tLSB) >> 6) / 4.0); // Allows for readings below freezing – Thanks to Coding Badly
//temp3231 = (temp3231 * 1.8 + 32.0); // Convert Celcius to Fahrenheit
return temp3231;

}
else {
temp3231 = 255.0; //Use a value of 255 to error flag that we did not get temp data from the ds3231
}

return temp3231;
}

byte read3AxisAcceleration()
{
Wire.beginTransmission(BMA250);
Wire.write(0x02);
Wire.endTransmission();
Wire.requestFrom(BMA250,7);
for(int i = 0; i < 7;i++)
{
dataArray[i] = Wire.read();
}
if(!bitRead(dataArray[0],0)){return(0);}

BMAtemp = dataArray[6];
x = dataArray[1] << 8; x |= dataArray[0]; x >>= 6;
y = dataArray[3] << 8; y |= dataArray[2]; y >>= 6;
z = dataArray[5] << 8; z |= dataArray[4]; z >>= 6;

BMAdata += String(x);
BMAdata += “,”;
BMAdata += String(y);
BMAdata += “,”;
BMAdata += String(z);
BMAdata += “,”;
BMAtempfloat = (BMAtemp*0.5)+24.0;
// add digits of BMAtempfloat value to datastring
BMAdata += ((int)BMAtempfloat);
BMAdata += “.”;
int temp = (BMAtempfloat – (int)BMAtempfloat) * 100;
BMAdata += (abs(temp));
//the following 2 lines also to convert float to string
//dtostrf(floatVariable2convert, minStringWidthIncDecimalPoint, numVarsAfterDecimal, charBuffer);
//for example: dtostrf(BMAtempfloat, 5, 2, dtostrfbuffer); dataString += dtostrfbuffer;
}

byte initializeBMA()
{
Wire.beginTransmission(BMA250);
Wire.write(0x0F); //set g
Wire.write(GSEL);
Wire.endTransmission();
Wire.beginTransmission(BMA250);
Wire.write(0x10); //set bandwith
Wire.write(BW);
Wire.endTransmission();
return(0);
}

long readVcc() { //trick to read the Vin using internal 1.1 v as a refrence
long result;
// Read 1.1V reference against AVcc
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Convert
while (bit_is_set(ADCSRA,ADSC));
result = ADCL;
result |= ADCH<<8;
result = 1126400L / result; // Back-calculate AVcc in mV
return result;
}

Walkin’ the walk…

I still have a long road ahead of me when it comes programming. But I figure that I since I started pretty near zero at the beginning of this project, I could share some thoughts on the process; before I forget what it was like. There were real benchmarks along the way, which made me feel pretty good when I achieved them, even if the goal posts seemed to move every single time.

Stage 1: Ummm, Is this thing on?

Initially, I was just reading the data from the sensors and sending that to the serial monitor to see what kind of numbers were being produced.  With the original Uno, and analog sensors like the MMA7260 this was just a few analogRead() statements. With a few simple lines of code, you know if you connected the wires properly. Still, it was cool to (carefully) move my little contraption around, see the numbers changing, and start thinking about how to calibrate the sensor, and whether I should  change AREF to get more juice out of the ADC. Also, to wonder if I should massage that data to get rid of all the jitter I was seeing in those numbers.

Stage 2: Going to the library.

Then I tackled writing the to the SD cards, copying code directly from the Adafruit datalogger shield tutorials. This introduced me to the concept of libraries: mysterious extra bits of code that I had to go find, and then #include with the program, to get the Arduino sketch to work. This was true for the SD cards, the RTC, and basically anything else that sent information to the microprocessor, rather than just putting a voltage on a pin.  These libraries are like the “killer apps” of the Arduino world. Without them, the best chip in the world remains unusable, hiding up in the rarefied atmosphere of embedded system engineers.  But as soon as one of those boffins decides to “release the library” he came up with for chip “IC-123”, then suddenly the forums light up, and all the lesser mortals start using that device in a big way.  Being one of those humbler people myself, my first step when wondering whether I can use a new widget, is to see if I can find libraries for it on github. And even though part suppliers like Adafruit, Sparkfun et. al. have turned this phenomenon into a thriving business model, the actual chip makers themselves almost never make the special sauce; leaving you to chew on the dry, salty, datasheets.

Stage 3: Can you I2C me?

Pullup resistors added to the chronodot RTC

Getting different two wire interface chips to share the same data “party line”, has benchmark status for me, because it was the first time software issues really forced me to go back and learn about the electronics seriously enough to raise my game. I spent days trying to figure out what pullup resistors were really doing, and whether the different boards I was cobbling together had put just the right amount on the lines. This was an important issue to resolve before moving on to the next stage of the game, but it also changed my understanding from “It either works or it doesn’t”, to the realization that there are many shades of grey in the way circuits are designed. Generally speaking, you get what you pay for.

Stage 4: Does this thing run on batteries?

Once all the chips were on speaking terms, and the data was being recorded on the SD card, it was time to cut the umbilical.  From a benchmark point of view, this is were all the software power management strategies come into play: the sleep codes really had to work, and the SQW alarm pulse had to wake the whole thing up again.  I also had to think about what would happen to all the circuits as the voltage started dropping. I had to learn about things like voltage regulators & level shifters, trying to find the weakest link in the chain, and then dug further into the forums to find out how far outside the specs you could actually go before you got into trouble.  In my project for example, I had prevent memory card writing if the voltage got too low or I would toast the memory cards, and loose all the data.

Stage 5: To infinity and beyond…

So this where I am now, and I am sure that there are many more “stages” ahead of me. The units are working for a reasonable length of time on batteries, but I still need to multiply that by a factor of two or three, to reach my year+ run time target. Preserving every last micro amp raises issues like data buffering to reduce the power hungry SD writes. This takes me even further into programming issues like variable optimization, because the code I cobbled together is now so large, that memory management is has become crucial. Or, if i work on my chops, I might be able to eliminate the SD cards entirely, and use eeproms for storage. Of course, each time I add a new chip or sensor into the mix, it sends me right back to stage 1 again.

The real take home message, for the people thinking about their first Arduino project is this: At each step of the way, getting a piece of  hardware to work required me to learn more programming, and each software problem I faced, forced me to learn more about the devices I was trying to connect. It’s sort of like climbing a ladder, by lifting one leg, and then the other. And as I passed each stage, the previous code folded into one small corner of the next version, adding layers of complexity like an onion. But I had no idea this was what the process would actually be like when I started out, because almost every thing I read at the time seemed to be written by technical geniuses that don’t have time for this kind of retrospective stuff.

 

A note on using the TinyDuino platform

_IGP9121I thought it might be good to put a few words in here on working with the Tinyduino system, because, although I really love the small footprint, and power optimization, you could say they were a “trial by fire” for someone with basic soldering skills.  Initially, I took one of their protoboards and added three rows of jumper pins to connect my RTC. This appeared to go ok so I painstakingly did this to all the proto-boards I had on hand.

But while it all seemed to go pretty well at first, I just could not get the darned RTC to work reliably.  I labored long under the chrondotassumption that I was making mistakes in the code (which hey, I probably was), or I had not pulled up the I2C bus properly, or there was something else I just had not learned yet. I eventually discovered that the tiny protoboard was slowly bending under the force of the jumper wires themselves, loosing contact with the stack, or shorting out on the layer below ( I did not have spacers in place to prevent this). And even when I fixed that, I still had weird intermittent faults occurring. Nothing is more frustrating than something that works fine most of the time, but then randomly cuts out on you.

_IGP9129In the end it turned out to be bridging between those really small contacts. I must have done it when I was soldering the pins on, but even after really close inspection, I could not see the bridge anywhere.  I ordered more boards, and started soldering thinner wires directly on, but then the wires themselves started breaking, because they were so fragile. I eventually figured out how to add some extra “support solder” by folding the wires over into a bit of ‘J’ hook, but even then they still couldn’t take much jostling around.  Now, I know there’s plenty of people out there just waiting to post a comment like: “If you are not already working with surface mount, just go home rookie”.

But I made this project blog in the hope that it might help other folks get rolling, so if, unlike me, you still have all your hair: do yourself a favor and buy a really good temperature controlled soldering iron, with ultra fine points in ‘mint’ condition. And I would recommend a fair bit of soldering practice, with a solder wick, before you jump in on those 0.1 inch Tinyduino proto-boards. Even then, buy extras, because you are probably going to go through them much faster than you think. I know I did.

Addendum 2014-02-10
And you don’t need to replicate my errors here any more because Tiny-Circuits has released an extended protoboard that you can buy naked for $5, or with terminal blocks!  These let you place the extension board in the middle of the tinyduino stack &  with all that extra space, I have soldered of riser pins on dozens of those new “double-wide” proto boards without any problems.  Also I now use soft multi-strand test lead wire with silicone insulation (instead of stiff PVC), which dramatically reduces strain on the solder joints.

A simpler housing design emerges.

I was happy with my Mark II design, but I realized that it was going to take half a day to make each one.  The latch clamps pushed the material cost to about $60, and the labor involved meant they were still going to be expensive in the kind of numbers Trish wanted for her network of cave sensors.  So I applied some thought to simplifying the design still further.

IMGP0029I had used some Fernco Quick-caps to convert the earlier botched housing bodies into anchors. It only took about fifteen minutes to create a one-piece housing, based on those, and I did not have to sand down any o-ring seats. Dayam! But my excitement was tempered when I put them in water, as the rubber end caps were so heavy that they rolled the units over, even with batteries in the PVC cap.  So I needed to come up with a way to attach these guys to the floor anchor, that maintained a rubber side down orientation. But I could not get anything to bond the flexing, bumpy outer surface of that rubber (which turned out to be “elastomeric pvc”)  In the end I threaded a fewIMGP0038 cable ties through pvc plugs, and suspending them under the pipe clamp. This worked but it only heightened my concern about the nature of the seal on these puppies. You see traditional O-ring designs actually work better on deep dives, because the added water pressure compresses the o-rings more tightly. This new design was super simple to build but it was also critically dependent on not one, but two pipe clamps made of metal, as I had to balance the mass of the clamp screw. Even with marine grade stainless, I had my doubts about the longevity of that seal. Nonetheless, I pressed on, and thought about a scaffold for the batteries and sensor package. A bit of IMGP0033ply, some hard foam insulation, and a touch of gorilla glue (an adhesive on my top five list of bodging materials) produced a battery compartment and electronics platform under 25 grams.  I added a ballast mass post with an old Ikea door pull, and put one of my new Tinyduino stacks into place. The hold down screws they came with were not long enough to penetrate that wood, so I had to fashion a U bend out of brass wire to affix the electronics.
Flow Sensor Housing by Edward Mallon

So now I had two different sensor housing designs. The more robust, o-ring design was expensive and took ages to make, while the simpler quick-cap housing, at about $10 material cost, it was definitely “Cheap as chips”, but it’s integrity relied on a couple of metal pipe clamps. I would not know if we had a winner until the next field work trip in late November. But even if this second design didn’t handle the water pressure at depth, I knew it was going to be handy for other cave research, because it was still a decent enough waterproof enclosure for less demanding environments.

<—Click here to continue reading—>

Underwater housing: Mark II

LeakEventually the “wobbly” enclosures made their way back to my workbench, and upon opening them I discovered that they had all leaked. But determined to improve the design, I scraped off the surface rust and began the post-mortem. Pressure from the latch clamps had actually separated the o-ring seats from the main body, damaging the o-rings. But it looked like I might have damaged the adhesion well before that, with all the grinding I had done in my quest for more buoyancy.

3accross

So the first step was to make the end caps bigger, and move the upper latch clamp ring further away from the delicate o-ring seat. Then I lengthened the support struts along the bottom shell, carefully gluing them into place with clamps. Once the latch clamps were attached, I thought about how I was actually going to place the electronics inside housing. Using Lego blocks as a proxy for some of the parts, I experimented with many different configurations attached to knock-out caps which kept everything level inside the housing. In the process I made the happy discovery that you can solvent weld the ABS bricks together, and they will also bond reasonably well to the caps, provided you use “just enough” solvent to bond the surfaces without softening them. As they say: “Many Bothans died to bring us this information…”

3accross-2

In the end I decided to put the power block into the bottom of the unit, and use a second knockout cap as the platform holding the electronics in the top half of the unit, I would figure out how to connect them later via some kind of power plug.

BalastI was really happy with the new housing, as the clips applied a nice even compression to the o-ring, and the overall unit just “felt right” to my divers hands.  With the batteries held securely in place by a scaffold of Lego, the bucket buoyancy tests looked good, showing no torque from the uneven weight distribution that plagued the first builds. But it was riding pretty high in the water, and I need them to be “just barely positive” if they were going to respond well in low flow conditions.  So I added a few ballast washers to both the top and bottom clam shells, and the Mark II housing was finally complete.

Flow Sensor Housing by Edward Mallon

It was now somewhere past 2 AM, and my wife, who had been on some sort of Skype call to another time zone, came down to the workshop to suggest that we call it a day.  But I was in pretty good spirits at at this point, and like a proud father, I started showing off my new baby as it bobbed up and down in the laundry tub. She was trying to smile, but the air was still pretty thick with the PVC/ABS solvent I had been using. And she couldn’t help but notice the small piles of half melted Lego scattered around the workbench.  While I was babbling, she slid a phone out of her back pocket, and just before capturing the above photo, she quips “You know, other women loose their men to football, or video games, but I end up with one who hides down in the basement, playing with Lego!”

<—Click here to continue reading—>

Addendum 2014-06-01: Just a note for any other underwater DIY’ers out there:  my
housing design has changed significantly since this build. I have now moved away from metal latch clamps to a system of nylon bolts around the perimeter.  See photos here.

 

Switching to the low power TinyDuino platform.

After sending the first gen housings out for some real world testing, I returned my attention to the guts of my data loggers.  While the Uno & Adafruit data logging shield was dead easy to get up and running, the whole unit would wring out 6AA’s in about a day, and I needed a heck of allot more run-time than that.

So I started combing through the forums at the Arduino playground for any power management threads I could find. A myopia inducing week of screen reading later, I had developed a rough list of strategies to pursue, even though I had no idea how much difference each one would make. These fell into two basic categories:

Lower the voltage & clock frequency,  then get rid of any circuits you don’t need:
– like indicator leds, voltage regulators, usb interfaces, etc

and once you have that sorted:

Turn off parts of the processor you are not using with software:
– and if possible put the whole chip to “sleep”

And although I did not find this mentioned anywhere, I also penciled in a note to research different battery chemistries, as I knew that on year long time scales, self discharge was going to be a real issue.

So I started with the hardware, and dug into the stunning array of “bare bones” clones that had spun off since Banzi et.al gave their little project to the world. I whittled the list down to a handful of low power units including: the Pro Mini,  the Solarbotics Ardweeny, the Rocket Scream Mini Ultra, Modern Device Jeenodes, RFduinos, and a few others that seemed to be pushing the limits of low power design. Some of these designs were so minimal, they were barely more than a row of breadboard pins soldered onto the raw Atmel chip itself. So, for a while, I flirted with the idea of just sticking a chip on a mini breadboard and going from there.

I was comfortable with the idea of using a separate FTDI breakout board to program the unit, but some of the low power designs had non standard processor chips, and I knew that was not going to work, because I was still cutting my teeth on “Coding for Dummies” tutorials. And on a purely practical level, the mini breadboard I used with an Ardweeny started getting ugly once I wired in the SD card shield, the accelerometer, the FTDI chip, the battery connectors, etc.  I was not sure the resulting octopus would survive the bashing around these sensors were likely to see dangling from the side of a cave diver, no matter how tough my housings were.

Then, I got wind of a spectacularly successful Kickstarter campaign  for a new, ultra small Arduino board that was being made in Ohio, and everything just fell into place.  While the new TinyDuino system was a bit expensive, it delivered almost everything on my power management wish list and they also had an accelerometer, an SD card shield, with several protoboards.  But rather than describe the effect of all this with words, perhaps a picture would convey all this a little better:

Alpha VS Beta

My digital innards went from an alpha kludge to a running beta in one fell swoop!

So although I had some misgivings about their fragile looking stack connectors, adopting the Tinyduino meant that I could now start chewing on the gnarlier bits of software based power management.

The hardware selection had essentially just been one long process of elimination, but I knew right from the start that coding would put me on a much steeper learning curve. AVR assembly language still seemed like quasi magical incantation, so I just started gathering every example of “sleep code” I could find, like a squirrel collecting nuts for winter.  I figured I would just try to  cut & paste from simple examples like the Nightingale code until I was successfully shutting down the cpu, and waking it with the internal watchdog timer on eight second cycles, to check if it was time to read data.

But I kept finding comments in the forums about how sloppy the Atmel internal clocks could get, affected by everything from temperature variations and input voltage, to “animal spirits”.  With so many iterations needed to extend those “overflow interrupt” blips out to a real world sampling cycle of perhaps 15 minutes, or even an hour, I worried that even tiny timing errors would eventually accumulate into sizable ones. (And recently I have heard rumors of people locking up their Arduinos because of watchdog timer conflicts with the default bootloader)

So I started investigating the use of an external real time clock (RTC) to let the little logger sleep for extended, and hopefully more precise, times between wake cycles.  There were tantalizing clues out there that this could make a system run for years, but I could not  follow the discussions far enough into the technical brambles to really understand them. And if I had thought that the machine code for sleeping was hairy, trying to pick a suitable RTC by looking at libraries and data sheets, seemed like it might convert an already steep learning curve into a straight vertical line.

Fortunately, it was then that I found an excellent post on power saving techniques which had clear examples of how to both sleep, and wake up the cpu with alarm interrupts. I was back in the game, and for the first time I had a sense of what all these things were actually contributing to my overall power budget. Combining his I2C primer  with the DSS circuits post on the Effects of varying I2C pull-Up resistors, and a few more tweaks, I finally managed to get a chronodot RTC (on the left in the picture above) to wake my sleeping data logger at any time interval I wanted.

Whew! My little project was finally looking like it might go the distance, and I was thanking the Gods for mysterious Über-tecks on the other side of the world, like Nick Gammon, who had put their mild obsessive compulsive disorders to such great effect bailing out newbies like myself.

<—Click here to continue reading—>

The “Alpha” build (of an underwater sensor housing)

Although the dive-light forums had convinced me to use PVC tubing as my housing material, I still had some significant design issues to work out. How big were these things going to be? How was I going to seal the unit under water? How was I going to actually install it in the caves? etc. I spent so much time rummaging through the plumbing isle looking at fittings, that the staff at my local hardware store were starting to run the other way whenever they saw me step over the threshold. And the ones I did capture, with my half baked story about what I was trying to do, had a kind of “There but for the grace of God go I…” expression creeping across their faces. Of course, after years of exposure from my own friends and family, I guess I am just used to it now 🙂

Anyway, I started out with three inch pvc pipe, for the simple reason that this had the smallest inner diameter that would hold my “alpha” Arduino Uno datalogger. But how was I going to OringSetuphold it together? Bolts?  Bungees?  I had seen plenty of latch clamps designs on the newer lights from Dive Rite, etc., but they all seemed to use machined rod stock with turned threads and special holder grooves for the O-rings. And this was more complicated than I wanted to go.  Fortunately, while I was working this out, I came across a miniDV housing instructable with a really nice system for backing an O-ring on a pipe. I realized that my housing could use this idea, but I did not need any of the clear windows or other things that complicated his design. Yes!

4" rings over 3" end caps

4″ pipe rings over 3″ end caps formed the basis of my housings

In fact all I really needed was two end-caps and a short length of pipe and I would have something that presented a nice smooth profile to the water flowing around it. But to connect the latch clamps I would need much thicker walls, or the screws would puncture the housing.  A bit more noodling around and I made the happy discovery that the inside diameter of 4″ pipe just barely goes over a 3″ pvc endcap, and the two solvent weld together nicely. Of course, hand sanding those matching faces down through to 600 grit took a while, but I was left with a nice smooth polish on the O-ring seats.

Getting down to 600 grit takes allot of hand sanding.

Getting those O-ring seats down to 600 grit takes quite a bit of sanding.

It took ages to find marine grade latch clamps, and I was surprised to find them costing $15 to $20 each. (After a great deal of time reading spec sheets, I found the cheapest clamps and O-rings at amazon – I will post a complete parts list for those later). So I had a basic “latch clamp & clam shell” idea percolating away. But how was I going to suspend this thing in the water column? Initially I had thought that I would simply run a bit of fishing line up to the float, but as I thought more about what the 3-axis accelerometer was actually doing, I realized that I could get much more than a simple tilt angle out of it:

If I could keep the unit from rotating, I would also get the direction of the water flow from the same sensor data! This realization was at the heart of the question of how to suspend the units inside the flooded caves.

So I need 180 degrees of freedom on the anchor points, but no rotation about that axis, or the direction information in the data would become meaningless as the sensor spun around. I suppose I could have just put a compass sensor in the unit and been done right there, but I had this sneaky feeling feeling that the problem could be solved more elegantly if I just burned a bit of midnight oil.

Corrosion had locked up some of our drip sensor tipping buckets a few years before.

Corrosion had locked up some of our drip sensor tipping buckets a few years before.

I started making all sorts of gimbals with hinges, bent wires, rods, bolts, springs, tubes, you name it, and I probably tried it. Most of them worked too, but they tended to be fiddly looking things that depended on one or more bits of metal, and I knew from previous projects that corrosion was eventually going to do them in. I also had to figure out how to attach those pivot joints to stiff rods, of varying lengths, which then somehow connected to the housing itself. On top of that, the whole assembly would have to gracefully fit inside a suitcase. And finally, just to complicate things still more, whatever I came up with had to be easily assembled in a dark cave, with a divers cold fumbling hands.

Well this little nut took me a few weeks to crack, and with all the factors in play, it represented the most complicated thing I had tackled on the project to date.  Especially with “easily repaired in the field” also echoing around inside my head.

Pivot joint with no rotation

Pivot joint with no rotation

But I am happy to reveal here, for the first time, a bodgers masterpiece of simplicity made with two cable ties, a length of pex tubing (cut into a washer), and a threaded pvc cap. I can whip up one of these puppies in about five minutes, from parts at any hardware store, and the pex tubing, which bends easily into a suitcase, is just barely positive under water…and there are no metal parts. With this in hand it was full steam ahead, and as soon as the latch clamps & 3 inch O-rings arrived (341 EPDM 70A) I would be ready to start testing the alpha build.

Boyancy testing

Buoyancy testing

But I ran into a bit of a snag when I started doing dunk tests: I had not really counted on the extra mass of the latch clamps (20g each), so with my rough calculations, I hadn’t left enough internal volume.  By the time I put my calibration mass (for the batteries, the Ardunio, etc) into the clam-shell, it sank like a stone. So I started drilling holes in the outer rings that the clamps were attached to, trying to increase the buoyancy so that the unit would just barely float when the simulated payload (about 220 grams) was inside it. The whole thing started to look like Swiss cheese.

One of the alpha housings, with anchor

One of the alpha housings, with anchor, and the short connector rod I made for the buoyancy testing.

Eventually, I ended up shaving most of the outer rings off the unit, which lead to several adhesion failures once the latch clamps started to apply pressure. But I just re-purposed those old shells into anchors with a rubber end cap. I had made a few shells, but I still had a pang of regret for the lost time, as I had spent more than an hour hand-sanding each of those O-ring seats. But the alpha housing build, minus electronics, was ready for testing. And just in time too, as this was early summer, and my wife had an undergrad about to leave for some fieldwork in Mexico. I made a few one meter support poles, stuffed the rest of the parts into a ziplock bag , and Trish passed this on to the student who flew out the very next day. I knew eyebrows might go up at the airport, but hopefully my weird collection of plumbing parts would not give the student too much grief from the airport security scanners. And even though the student was keen to help out, I knew that like anyone doing fieldwork, they already had a to do list that was larger than their available time. So there was a good chance they were not going be able to throw my contraption in the water and to see how it behaved.

I went back to developing the electronics side of things over the next couple of weeks, but I felt like a penny waiting for change each time I asked if the housing had been tested, and found out that, no, they had not had a chance to put it in the water. Not yet.

Then one morning over coffee, my wife says: “Oh, yeah. (the student) is back from her field work.”

My eyes widen, “And? Did the units go in? Did the floats respond to the water flow?”

“She put them in at one of the outflows along the coast” she replied, “And they seemed to respond to the direction of flow pretty well….”

“Mmmm, why do I hear a “But” coming…What actually happened?” I asked.

“She says that they wobbled.” and then she added,”Sort of wiggling around as they tilted in the direction of the current. But the flow’s pretty strong there, so it could have just been regular eddy currents. You see that in the seaweed along the bottom all the time…Then they sank.”

Trish wasn’t too worried about this news but I was a bit stunned. I had been expecting something like “it sank”, or “moved slowly”, or “no response at all”, but I was not prepared for “wiggly & wobbly”.  I spent that morning in front of Google, trying to learn something about fluid dynamics, and specifically, the phenomenon of: “Bluff Body Vortex Shedding“. My heart was sinking with each new read because this had the potential to introduce so much noise in the accelerometer’s signal, that the data would be useless.

So we had run into a piece of fundamental physics that might kybosh the whole project. I was pretty bummed out that day, because even when I did start to understand the math, sort of, I still could not see any way around the problem. Fortunately for me, I was about to get some really good news on the electronics side of things, which had me doing my  ‘happy dance’, which, on reflection, was probably a bit “wiggly & wobbly” too.

<—Click here to continue reading—>

Initial research for the submersible housing.

Well, as luck would have it, the flow sensor project went on hold for most of 2012, as I had become the lead illustrator for a very cool book project, and we had recently purchased a circa 1890 Sears kit home, that was desperately in need of some tlc.  But in between ripping all the original wood siding off the house, repairing the windows, painting, or laying in a new patio, I was still reading as much as I could about the Arduinos, and learning quite a bit from books like Arduino Projects to Save the World which showed me all sorts of tricks I could use with real time clocks, eeprom memory, bare bones Arduino clones, etc. I went to a couple of Maker Faires to meet new people, started keeping an eye on kickstarters, and finally began to understand why my brother had been going on about how cool the open source movement was for all these years.

So at the start of 2013,  I had a 500 pound gorilla in the room: No matter what I did on the electronics side of things, I still had to come up with something that was going to protect those circuits at depth for a really long time. While it doesn’t look like much summarized here, this background research actually took quite a while ( I have hundreds of links in a Google doc somewhere…), so I am posting the highlights here in the hopes that it might help someone else save a bit of time.

OtterlightMy first thought was to take an enclosure that was already water proof, like an otter box or a pelican case, and just stick a few cable glands on it. I had often stumbled across projects like this in the cave diver forums, where someone always seemed to be building their own lights. I even bought a few cases to try it out, but for the most part, I really didn’t think I could trust those feeble O-rings for the job. On top of that those cases were oddly shaped, and I did not want to use something that presented dramatically different cross sectional area with different orientations relative to the water flow.

RedCamAnd then I found several people building underwater video camera housings.  These guys were getting serious! Perhaps the best one out there is the one by Bobby_M on the instructables site. But there were plenty of others of the same caliber and untold thousands of other designs to burn away the hours on YouTube. For the most part though, these guys were building really big units, with budgets for the housing alone that went over the target for my whole project. But I still picked up a few handy sources for critical parts, like latch clamps & O-rings.

submarineBut the high point of my underwater housing research was the discovery of the home built R.O.V. crowd. Yep, you too can build your own undersea robot. If there is a way to build something that goes below sea level, you can bet that these guys have tried it out. I learned quite a bit reading through their design blogs, especially about things like potting your electronics in wax (which I still have yet to do) and tricks like using bolts, rather than expensive clamps, to seal the ends with home made bell joint leak clamps.

However, after all of that, I ended up back to where I started. You see back when my wife was a starving grad student, we really didn’t have two nickles to rub together. So most of our kit was cobbled together from old equipment other people donated to us (and to whom we are forever grateful). So we ended up cave diving with huge old canister lights, powered by lead acid motorcycle flat stockbatteries, and not a few of those were home made because that’s just how things were done in the early days.  But the thing is, by the time we got them, those housings had already survived years of abuse, proving their worth. So I set off again rooting through the archives, for the “really old” dive light builder threads, which in the end, turned out to be GOLDMINES of information. These guys were starting with cheap PVC piping, heat gunning them into workable hunks of flat-stock, and some even figured out how to lathe end caps using only a hand drill and a chisel.  After seeing all that, and the straightforward simplicity of the construction,  I was pretty much set on using PVC pipe as the building material for my housing, rather than expensive rods made of nylon, or ABS.

<—Click here to continue reading—>

The original float/pendulum idea

Once I had seen the old fashioned air speed indicators, it did not take me long to find references to an even older idea: the hydrometric pendulum. (mentioned in books as old as 1884) So a simple pendulum (or float!) would indeed work if I was able to measure the angle of deflection.  I scribbled a few doodles down on a piece of paper, and ran in to my wife’s office at Northwestern University to discuss it with her. At the time, she was conducting a lab session with her instrumentation students, so they also got an earful of my enthusiasm, which amused everyone.

I don’t have any of those original “back of the envelopes”, but I did find one of my early concept drawings from some time in February 2011:

Original concept sketch from 2011

Original concept sketch from 2011

As you can see from the picture I figured I was going to need a really big battery in a heavy enclosure resting on the floor of the cave, so I initially conceived of the device using a float rather than a pendulum. I was still trying to figure out some way to actually measure the angle of deflection without breaking the integrity of the underwater housing because I knew each gasket or o-ring was just another potential point of failure. I had some idea of just attaching the bobber to a joystick mechanism, and one friend suggested putting magnets on the string and using hall effect sensors in the case.

But I was still trying to figure out how it might be possible to put everything, including the sensors, inside the float itself. I soon discovered from the Arduino forums I was rummaging through that there were plenty of people using accelerometers in tilt sensing applications very much like this, for robots, quad copters, and even one fellow who put a datalogger with an accelerometer on his garbage can.

One of the prototypes from 2011. (held together with hot glue.)

One of the prototypes from 2011. (held together with hot glue.)

So I set to work building prototype data logger / accelerometer combination, bootstrapping myself on the arduino micro-controllers with the many helpful tutorials at Adafruit Industries , and of course the Arduino playground.  I was, and still am, beholding to the many people who share their expertise so freely in the open source hardware community. And I managed to cobble together a couple of dry prototypes (that actually recorded data) near the end of 2011, which I dragged around at Christmas of that year, doing show & tell sessions with my more technically able friends. My wife, bless her, put up with “Ed’s latest project” evangelism, even though I had melted my way through most of the drinking cups in the kitchen, and the house was beginning to take on the distinct bouquet of poor soldering & burnt plastic. At the time I was using a vanilla Arduino Uno, with an Adafruit data logger shield.  To that I had added the MMA7361 from modern devices as the accelerometer, and the whole thing gave me a whopping 24 hours of run time out of 6 AA batteries.  Not exactly the year’s worth of data we were hoping for but I had managed to cram all of that into a hunk of pvc pipe from Home Depot, so the “all in the float” approach was looking like it might just be possible.  I still had not given anything a “dunk” test yet, but at least it was a start.

<—Click here to continue reading—>