Arduino GSM shield

This week’s project: setting up this Arduino with GSM shield to monitor the UPS that powers my mass specs. If we get a power cut (or when- this is Auckland after all) it will send me an SMS so I can race in and shut the mass specs down before they crash. Full write up when I’ve managed to make it all work.

🙂

NB Apologies for the repost but tumblr didn’t want to load the image for yesterday’s post. 

Advertisements

selectInput() and while() loop headaches in Processing 2.2.1

I’ve been working on a Processing sketch that uses a selectInput() dialogue to ask for a CSV file. The example in the Processing reference doesn’t work very well because the sketch doesn’t pause and wait for you to select the input. It opens a open-file window and then immediately skips on to running rest of the code before you’ve selected your file, which predictably crashes because it contains references to a file that hasn’t been selected yet and so resolve to null.

A solution proposed on the forums is to add a while() loop after selectInput() which pauses the sketch while the selected file == null. As soon as you’ve selected the file you want to work with this ends the while() loop and the rest of the sketch proceeds with the selected file, like so: 

String sourceFile = “pause”;

selectInput(“Select a file to process:”, “fileSelected”);  // select an AMDIS results file to process – MUST BE A CSV
while(sourceFile.equals(“pause”)) {}  // wait until a file is selected

This used to work in a previous version of the sketch I wrote but I’ve recently updated Processing to 2.2.1 and, of, course things that used to work now don’t. Grrrrrrr. This might be something to do with there needing to be at least one statement. For eg, if I put a println() statement in there it simply keeps printing the same thing until I’ve selected a file. This makes the while() loop fulfil its function in pausing the sketch but the looped process of printing a zillion strings to the terminal burns up processor time and can even make the whole sketch hang. An inelegant solution. 

As an alternative a post on StackOverflow (which is the most amazing hacking resource, by the way) offered an alternative code snippet utilising a different file open dialogue from the javax.swing library. This works perfectly, if still eccentrically as it uses the old XP style file open dialogue which defaults to the location of the desktop and requires much clicking if you happen to have a deep folder structure. As a plus though it allows you to use shortcuts to navigate, unlike the native Windows 7 file open dialogue, so a quick shortcut link to your data folder plonked on the desktop facilitates rapid access to your target. 

A couple of shots showing an Arduino Nano I’ve put into the aqualab to monitor the sump temperatures on the recirculation system for an upcoming ocean acidification project run by Kay Vopel (http://www.vopel.org/). The Nano is reading two waterproof DS18B20 temperature sensors, one in the sump and one on the outflow from the mixing barrel, as well as a DHT22 air temperature & humidity sensor. The sensors are fed through holes melted in the HDPE of the little tupperware container its mounted in and the holes have been sealed with hot glue. The Nano is on the end of a 5m USB cable that stretches over to the PC on the bench opposite.

The monitor is showing my Processing datalogger sketch running. There’s two incidences of the sketch running, as there’s two recirculation system so there’s two Arduinos. The second one doesn’t have a DHT22. The data is plotted, shown numerically at the top of the screen and logged to text file. One day I’ll hack out a solution to read data from two Arduinos into one sketch but for now this was a quick and dirty solution.

Both plots show a pink and a yellow line climbing gently across the screen. These are the water temperatures. The MSc student increased the temperature on the water cooler yesterday and the system’s still equilibrating. The blue zig-zag line shows the air temperature bouncing up and down as the aircon switches on and off.

design: magazine rack

My wife keeps a large number of glossy magazines around the house which always seem to end up in piles wherever I want to put my cup of tea down. So I set about designing a rack I could laser cut out of 6mm MDF and then screw to the wall to provide my dearest with somewhere convenient yet tidy to keep them. Once I had the basic design I set about crudely baroquing it as I like pretty patterns. 

😀

This is a single rack design which I think might be appropriate for the bathroom. I’m also going to tweak the design to add racks vertically or horizontally to house more extensive collections.

Auckland Winter humidity problems

I’ve got a climate datalogger in my house here in West Auckland. Its based on an Etherten from Freetronics, which is an ethernet-enabled Arduino Uno compatible board. On that is sat a wing screw shield for easy connection of wires and on top of that is sat an Adafruit LCD shield showing the readings.

image

Inside or outside it are a DHT22 temperature and relative humidity sensor, a BMP085 air pressure and temperature sensor, a DS18B20 temperature sensor and a light dependent resistor. The sensors are polled every 20s and the data uploaded to Xively. The BMP temperature sensor reads a few degrees high because its inside the plastic box, exposed to the warmth from the circuitry. The DS18B20 generally reads a couple of degrees low because its hanging down the back of the shelves the logger sits on, away from ambient air movement (although this is, of course, still interesting [to me, anyway]). The whole affair runs off a 5V power supply connected by USB. 

Here’s a shot of the log from the last few days. The gap in the data is where the logger hung and had to be reset, by the way.

As you can see, after a series of cold, wet days- indicated by the small peaks in the ‘light’ plot at the top left- relative humidity climbs to nearly 100%. This is despite us leaving the heat pump and a pair of heaters running all night. This was not helped at all by the need to dry clothes inside when its too wet outside, adding to the moisture in the air.

As a consequence I now have mould growing on the shelves in my bedroom!

image

Yay, for houses with poorly fitting, single-glazed windows and no insulation!

Here’s the Arduino sketch, if anyone’s interest.

#include <SPI.h>
#include <Ethernet.h>
#include <HttpClient.h>
#include <Cosm.h>

// ! ! USB DEBUG OPTION ! !
int debug = 0;

// Sensor setup
#include “Wire.h”
#include “Adafruit_BMP085.h”
#include “DHT.h”
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Adafruit_MCP23017.h>
#include <Adafruit_RGBLCDShield.h>

// MAC address for your Ethernet shield
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip (192,168,1,65); // Available Static IP address on your Network. See Instructions

// Your Cosm key to let you upload data
char cosmKey[] = “@@@@@ your key goes between the quotes here @@@@@@@”;

#define FEED_ID 76854;
unsigned long feedID = FEED_ID;

// Define the strings for our datastream IDs
char sensorID0[] = “BMPp”;
char sensorID1[] = “DHTh”;
char sensorID2[] = “DSt”;
char sensorID3[] = “light”;
char sensorID4[] = “BMPt”;
char sensorID5[] = “DHTt”;

CosmDatastream datastreams[] = {
CosmDatastream(sensorID0, strlen(sensorID0), DATASTREAM_FLOAT),
CosmDatastream(sensorID1, strlen(sensorID1), DATASTREAM_FLOAT),
CosmDatastream(sensorID2, strlen(sensorID2), DATASTREAM_FLOAT),
CosmDatastream(sensorID3, strlen(sensorID3), DATASTREAM_FLOAT),
CosmDatastream(sensorID4, strlen(sensorID4), DATASTREAM_FLOAT),
CosmDatastream(sensorID5, strlen(sensorID5), DATASTREAM_FLOAT),

};
// Finally, wrap the datastreams into a feed
CosmFeed feed(feedID, datastreams, 6 /* number of datastreams */);

EthernetClient client;
CosmClient cosmclient(client);

// LCD shield

Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();
#define WHITE 0x7

Adafruit_BMP085 bmp;
//
//// Data wire is plugged into which pin on the Arduino?
#define ONE_WIRE_BUS 6
//
//// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
//
//// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

#define DHTPIN 3 // what pin we’re connected to
#define DHTTYPE DHT22 // DHT 22 (AM2302)
DHT dht(DHTPIN, DHTTYPE);

float light;

void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
lcd.begin(16, 2);
lcd.setBacklight(WHITE);
lcd.print(“initialising”);

Serial.println(“Starting single datastream upload to Cosm…”);
Serial.println();

if (debug < 1 ) {

while (Ethernet.begin(mac) != 1)
{
Serial.println(“Error getting IP address via DHCP, trying again…”);
Serial.println(millis());
// lcd.clear();
lcd.setCursor(0,0);
lcd.print(“Error getting IP”);
lcd.setCursor(0,1);
lcd.print(millis()/1000);
delay(5000);
}
}

// set pin modes to power sensors
pinMode(7, OUTPUT);
pinMode(5, OUTPUT);
pinMode(4, OUTPUT);
pinMode(2, OUTPUT);

digitalWrite(7, LOW);
digitalWrite(5, HIGH);
digitalWrite(4, LOW);
digitalWrite(2, HIGH);

// initialise sensors
bmp.begin();
dht.begin();
sensors.begin();

delay(100);

}

void loop() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(millis()/1000);

// Get sensor readings
// BMP085
float BMPt = bmp.readTemperature();
float BMPp = bmp.readPressure() / 100.0;

// DHT22
float DHTh = dht.readHumidity();
float DHTt = dht.readTemperature();

// DS18B20
sensors.requestTemperatures(); // Send the command to get temperatures
float DSt = (sensors.getTempCByIndex(0));

// get light
light = analogRead(0)/ 10.23;

datastreams[0].setFloat(BMPp);
datastreams[1].setFloat(DHTh);
datastreams[2].setFloat(DSt);
datastreams[3].setFloat(light);
datastreams[4].setFloat(BMPt);
datastreams[5].setFloat(DHTt);

if (debug > 0) {

/*———–( Show the values inside the streams for test/debug )—–*/
Serial.println(“—–[ Test: Check values inside the Streams ]—–”);
Serial.print(“BMPp: ”);
Serial.println(datastreams[0].getFloat()); // Print datastream to serial monitor
Serial.print(“DHTh: ”);
Serial.println(datastreams[1].getFloat()); // Print datastream to serial monitor
Serial.print(“DSt: ”);
Serial.println(datastreams[2].getFloat()); // Print datastream to serial monitor
Serial.print(“light: ”);
Serial.println(datastreams[3].getFloat()); // Print datastream to serial monitor
Serial.print(“BMPt: ”);
Serial.println(datastreams[4].getFloat()); // Print datastream to serial monitor
Serial.print(“DHTt: ”);
Serial.println(datastreams[5].getFloat()); // Print datastream to serial monitor
delay(2500);
}

if (debug < 1) {
Serial.println(“Uploading to Cosm”);
lcd.clear();
lcd.setCursor(0,1);
lcd.print(“sending to COSM”);
int ret = cosmclient.put(feed, cosmKey);

Serial.print(“COSM client returns: ”); // Get return result code, similar to HTTP code
lcd.clear();
lcd.setCursor(0,0);
lcd.print(“COSM client”);
lcd.setCursor(0,1);
lcd.print(“returned: ”);
Serial.println(ret);
lcd.print(ret);
Serial.println();
delay(500);
lcd.clear();
lcd.setCursor(0,0);
lcd.print(“BMPp: ”);
lcd.print(BMPp);
lcd.setCursor(0,1);
lcd.print(“BMPt: ”);
lcd.print(BMPt);
delay(3500);
lcd.clear();
lcd.setCursor(0,0);
lcd.print(“DHTh: ”);
lcd.print(DHTh);
lcd.setCursor(0,1);
lcd.print(“DHTt: ”);
lcd.print(DHTt);
delay(3500);
lcd.clear();
lcd.setCursor(0,0);
lcd.print(“light: ”);
lcd.print(light);
lcd.setCursor(0,1);
lcd.print(“DSt: ”);
lcd.print(DSt);
delay(3500);
}
}

logging thermocycler performance

My favourite PhD student (hi, squids!) was having issues with her PCR. She was ending up with empty tubes at the end of her program and was concerned that the machine wasn’t producing the right temperature cycle. As I had an Adafruit MAX6675 thermocouple board on my desk I offered to log the cycle to determine whether this was the case. I used a miniature breadboard to connect the Arduino Nano and MAX6675 breakout. The measurements were output to serial and logged to text file by a PC running my Processing datalogger sketch. Here’s the result:

image

There seems to be some real issues here as the temperatures don’t match the program well at all. There’s meant to be a 55C step immediately before each polymerisation hold at 62C and the sensor gets no where near this. This might be a result of poor heat transfer between the reaction tubes and the thermocouple but I figure that accurately reflects the same process of heat transfer between the block and the liquid in the reaction tubes. 

I’ve run the test again in a different well on the block. I’ll need to validate the thermocouple’s temperatures using another couple of thermometers to make sure its giving accurate temps but just this initial test has revealed a problem worthy of serious investigation. The fun continues another day … .